home *** CD-ROM | disk | FTP | other *** search
/ Super PC 34 / Super PC 34 (Shareware).iso / spc / UTIL / DJGPP2 / CONTRIB / ASPI.ZIP / aspi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-25  |  4.0 KB  |  165 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <fcntl.h>
  5. #include <sys/stat.h>
  6. #include <go32.h>
  7. #include <dpmi.h>
  8. #include <sys/farptr.h>
  9.  
  10. #include "aspi.h"
  11. #include "aspi_int.h"
  12. #include "scsidefs.h"
  13.  
  14. static int TB;
  15. static int DB;
  16. #define DOSS    _go32_info_block.selector_for_linear_memory
  17. #define INT    r.x.sp = r.x.ss = r.x.flags = 0, _go32_dpmi_simulate_int
  18. #define    __dpmi_regs _go32_dpmi_registers
  19. #define GTB (_go32_info_block.linear_address_of_transfer_buffer & 0xfffff)
  20.  
  21. union {
  22.   SRB_HAInquiry hai;
  23.   SRB_GDEVBlock gdb;
  24.   SRB_ExecSCSICmd srb;
  25.   SRB_Abort ab;
  26.   SRB_BusDeviceReset res;
  27. } SRB_Everything;
  28.  
  29. static aspi_fd = -1;
  30. static int aspi_entry_seg;
  31. static int aspi_entry_ofs;
  32. static _go32_dpmi_seginfo dos_buf;
  33.  
  34. long aspi_buffer_length = 128 * 1024;
  35. char aspi_sense[SENSE_LEN];
  36.  
  37. static void
  38. aspi_entry(void *srb, int srblen)
  39. {
  40.   __dpmi_regs r;
  41.   int i;
  42.   int sp = GTB + 4090;
  43. /*  printf("%x = %x + 4090\n", sp, GTB);*/
  44.   dosmemput(srb, srblen, TB);
  45. /*  printf("go32's TB at 0x%x 0x%x\n", _go32_info_block.linear_address_of_transfer_buffer, GTB); */
  46. /*  printf("entry: SRB at 0x%lx (dos TB at 0x%x)\n", srb, TB); */
  47.   memset(&r, 0, sizeof(r));
  48.   r.x.cs = aspi_entry_seg;
  49.   r.x.ip = aspi_entry_ofs;
  50.   sp -= 2; _farpokew(DOSS, sp, TB >> 4);
  51.   sp -= 2; _farpokew(DOSS, sp, TB & 15);
  52.   r.x.ss =  GTB >> 4;
  53.   r.x.sp = (sp -  r.x.ss*16);
  54. /*  printf("entry: go %04x:%04x, stack %04x:%04x (now 0x%x)\n",
  55.      r.x.cs, r.x.ip, r.x.ss, r.x.sp, sp); */
  56. #if 0
  57.   printf("stack[0x%x]: ", r.x.ss * 16 + r.x.sp);
  58.   for (i=0; i<37; i++)
  59.     printf(" %02x", _farpeekb(DOSS, r.x.ss * 16 + r.x.sp + i));
  60.   printf("\n");
  61. #endif
  62.   _go32_dpmi_simulate_fcall(&r);
  63.   while (_farpeekb(DOSS, TB+1) == 0);
  64.   dosmemget(TB, srblen, srb);
  65. }
  66.  
  67. int
  68. aspi_init(void)
  69. {
  70.   __dpmi_regs r;
  71.   SRB_HAInquiry hai;
  72.  
  73.   setbuf(stdout, 0);
  74.   dos_buf.size = (aspi_buffer_length/16) + (sizeof(SRB_Everything)+15) / 16;
  75.   if (_go32_dpmi_allocate_dos_memory(&dos_buf))
  76.   {
  77.     fprintf(stderr, "ASPI Error: Not able to allocate %d Kb buffer\n", aspi_buffer_length / 1024);
  78.     aspi_fd = -1;
  79.     return -1;
  80.   }
  81.   TB = dos_buf.rm_segment * 16;
  82.   DB = TB + (sizeof(SRB_Everything) + 15) & ~15;
  83.   
  84.   aspi_fd = open("SCSIMGR$", O_RDONLY);
  85.   if (aspi_fd < 0)
  86.   {
  87.     perror("SCSIMGR$");
  88.     aspi_fd = -1;
  89.     return -1;
  90.   }
  91.  
  92.   r.x.ax = 0x4402;
  93.   r.x.bx = aspi_fd;
  94.   r.x.cx = 4;
  95.   r.x.ds = TB >> 4;
  96.   r.x.dx = TB & 15;
  97.   INT(0x21, &r);
  98.   aspi_entry_ofs = _farpeekw(DOSS, TB);
  99.   aspi_entry_seg = _farpeekw(DOSS, TB+2);
  100.   close(aspi_fd);
  101.   aspi_fd = 0;
  102.  
  103.   memset(&hai, 0, sizeof(hai));
  104.   hai.SRB_Cmd = SC_HA_INQUIRY;
  105.   aspi_entry(&hai, sizeof(hai));
  106.  
  107.   return hai.HA_Count;
  108. }
  109.  
  110. int
  111. aspi_close(void)
  112. {
  113.   if (aspi_fd)
  114.     return;
  115.   _go32_dpmi_free_dos_memory(&dos_buf);
  116.   aspi_fd = -1;
  117.   return 0;
  118. }
  119.  
  120. int
  121. aspi_device_type(int aspi_id)
  122. {
  123.   SRB_GDEVBlock gd;
  124.   if (aspi_fd)
  125.     return;
  126.   memset(&gd, 0, sizeof(gd));
  127.   gd.SRB_Cmd = SC_GET_DEV_TYPE;
  128.   gd.SRB_HaId = ASPI_ID2HOSTAD(aspi_id);
  129.   gd.SRB_Target = ASPI_ID2TARGET(aspi_id);
  130.   gd.SRB_Lun = ASPI_ID2LUN(aspi_id);
  131.   aspi_entry(&gd, sizeof(gd));
  132.   return (gd.SRB_Status == SS_COMP) ? gd.SRB_DeviceType : -1;
  133. }
  134.  
  135. int
  136. aspi_exec(int id, void *buf, int buflen, int rw, char *cdb, int cdblen)
  137. {
  138.   char *cptr;
  139.   SRB_ExecSCSICmd srb;
  140.  
  141.   if (aspi_fd)
  142.     return;
  143.  
  144.   memset(&srb, 0, sizeof(srb));
  145.   srb.SRB_Cmd = SC_EXEC_SCSI_CMD;
  146.   srb.SRB_Status = 0;
  147.   srb.SRB_HaId = ASPI_ID2HOSTAD(id);
  148.   srb.SRB_Flags = SRB_DIR_SCSI;
  149.   srb.SRB_Target = ASPI_ID2TARGET(id);
  150.   srb.SRB_Lun = ASPI_ID2LUN(id);
  151.   srb.SRB_BufLen = buflen;
  152.   srb.SRB_SenseLen = SENSE_LEN;
  153.   srb.SRB_BufPointerOfs = DB & 15;
  154.   srb.SRB_BufPointerSeg = DB >> 4;
  155.   srb.SRB_CDBLen = cdblen;
  156.   memcpy(srb.cptr, cdb, cdblen);
  157.   if (rw & ASPI_RW_WRITE)
  158.     dosmemput(buf, buflen, DB);
  159.   aspi_entry(&srb, sizeof(srb));
  160.   if (rw & ASPI_RW_READ)
  161.     dosmemget(DB, buflen, buf);
  162.   memcpy(aspi_sense, srb.cptr+cdblen, SENSE_LEN);
  163.   return srb.SRB_Status;
  164. }
  165.